package com.turtle3d.user.grammars;

import java.util.ArrayList;

import com.turtle3d.formallanguage.grammar.Grammar;
import com.turtle3d.formallanguage.parser.SimpleParser;
import com.turtle3d.formallanguage.symbol.Method;
import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.formallanguage.symbol.SymbolClass;
import com.turtle3d.formallanguage.symbol.SymbolFactory;

public class IFSFern extends Grammar {

	public static final float scale = 0.4f; 
	
	@Override
	public void define() {

		setAxiom(SimpleParser.parseSymbolSequence("LRX"));

		SymbolFactory.getSymbolFactory().registerSymbolClass("S", "S(0.7)",
				new Method() {
					public boolean calculate(ArrayList<Symbol> symbolSequence,
							int symbolIndex, Symbol calculatedSymbol) {
						calculatedSymbol.setParameter(Symbol.SCALE_MULTIPLIER,
								0.7f);
						return true;
					}
				});

		SymbolFactory.getSymbolFactory().registerSymbolClass("S", "S(0.5)",
				new Method() {
					public boolean calculate(ArrayList<Symbol> symbolSequence,
							int symbolIndex, Symbol calculatedSymbol) {
						calculatedSymbol.setParameter(Symbol.SCALE_MULTIPLIER,
								scale);
						return true;
					}
				});
		
		SymbolFactory.getSymbolFactory().registerSymbolClass("S", "S(x)",
				new Method() {
					public boolean calculate(ArrayList<Symbol> symbolSequence,
							int symbolIndex, Symbol calculatedSymbol) {
						calculatedSymbol.setParameter(Symbol.SCALE_MULTIPLIER_X,
								-scale);
						calculatedSymbol.setParameter(Symbol.SCALE_MULTIPLIER_Y,
								scale);
						calculatedSymbol.setParameter(Symbol.SCALE_MULTIPLIER_Z,
								scale);
						return true;
					}
				});		

		SymbolFactory.getSymbolFactory().registerSymbolClass("+", "+(3)",
				new Method() {
					public boolean calculate(ArrayList<Symbol> symbolSequence,
							int symbolIndex, Symbol calculatedSymbol) {
						calculatedSymbol.setParameter(Symbol.TURN_ANGLE,
								calculatedSymbol.getParameter("turnAngle2"));
						return true;
					}
				});
		
		SymbolFactory.getSymbolFactory().registerSymbolClass("-", "-(60)",
				new Method() {
					public boolean calculate(ArrayList<Symbol> symbolSequence,
							int symbolIndex, Symbol calculatedSymbol) {
						calculatedSymbol.setParameter(Symbol.TURN_ANGLE,
								calculatedSymbol.getParameter("turnAngleLeftSide"));
						return true;
					}
				});
		
		addProduction(SimpleParser.parseProduction("L->F[-(60)S(0.5)!]"));
		addProduction(SimpleParser.parseProduction("R->+(3)F[+S(x)!]"));
		addProduction(SimpleParser.parseProduction("X->+(3)S(0.7)!"));

	}

	public void setRequiredParameters() {
		setRequiredParameter(Symbol.TURN_ANGLE, 80f);
		setRequiredParameter("turnAngle2", 4f);
		setRequiredParameter("turnAngleLeftSide", 60f);
		setRequiredParameter(Symbol.DISTANCE, 2f);		
		setRequiredParameter(Symbol.PITCH_ANGLE, 5f);
		setRequiredParameter("scaleMultiplier", 0.78f);
	}

}
